import Vue from "vue";
import $web3js from "../web3.js";
import $erc20Token from "../erc20Token/index.js";

const contractFactory = require("./IMdexFactory.json");
const contractInfo = require("./IMdexPair.json");
let contractAddress = "";

let web3 = $web3js.getWeb3();
let contractMap = new Map();
let contractConst = {
  contract: web3
    ? new web3.eth.Contract(contractFactory.abi, contractAddress)
    : ""
};

const handleContractEmpty = _defaultValue => {
  return new Promise((resolve, reject) => {
    resolve(_defaultValue);
  });
};
const getIMdexFactoryAddress = () => {
  return contractAddress;
};

const getIMdexFactoryContract = () => {
  return contractConst.contract;
};

const getPair = (tokenA, tokenB) => {
  return $web3js.commonCall(
    getIMdexFactoryContract().methods.getPair,
    tokenA,
    tokenB
  );
};

const getIMdexPairContract = _contractAddress => {
  let _iMdexPairContract = contractMap.get(_contractAddress);
  if (!_iMdexPairContract) {
    try {
      _iMdexPairContract = web3
        ? new web3.eth.Contract(contractInfo.abi, _contractAddress)
        : "";
    } catch (error) {
      Vue.prototype.$toast(error && error.message ? error.message : error);
    }
    if (_iMdexPairContract) {
      contractMap.set(_contractAddress, _iMdexPairContract);
    }
  }
  return _iMdexPairContract;
};

const getToken0 = async _contractAddress => {
  let contract = getIMdexPairContract(_contractAddress);
  if (!contract) {
    return handleContractEmpty("");
  }
  return $web3js.commonCall(contract.methods.token0);
};

const getToken1 = async _contractAddress => {
  let contract = getIMdexPairContract(_contractAddress);
  if (!contract) {
    return handleContractEmpty("");
  }
  return $web3js.commonCall(contract.methods.token1);
};

const getReserves = async _pair => {
  let contract = getIMdexPairContract(_pair);
  if (!contract) {
    return handleContractEmpty("");
  }
  return $web3js.commonCallAndHandlerParams(
    contract.methods.getReserves,
    handleReserves,
    [_pair]
  );
};

const getPairTotalSupply = async _pair => {
  let contract = getIMdexPairContract(_pair);
  if (!contract) {
    return handleContractEmpty("");
  }
  return $web3js.commonCallAndHandler(
    contract.methods.totalSupply,
    $web3js.fromWei
  );
};

const handleReserves = async (res, _pair) => {
  // console.log(res)
  let index = 0;
  let reserve0 = res[index++];
  let reserve1 = res[index++];
  let blockTimestampLast = res[index++];

  let token0 = await getToken0(_pair);
  let token1 = await getToken1(_pair);
  reserve0 = await $erc20Token.fromErc20TokenValue(reserve0, token0);
  reserve1 = await $erc20Token.fromErc20TokenValue(reserve1, token1);

  return {
    reserve0,
    reserve1,
    blockTimestampLast,
    token0,
    token1
  };
};

export default {
  getIMdexFactoryAddress,
  getIMdexFactoryContract,
  getIMdexPairContract,
  getReserves,
  getPair,
  getPairTotalSupply
};
